<?php
class Ext_Model_WSProxyServer
{

    /**
     * Api privada y generica usada desde WSProxy.
     * ClassId es un uniqueId que permite identificar la clase para que
     * se puede mantener el estado del lado del server.
     * @param string classId
     * @param string className
     * @param mixed constructorArgs
     * @param mixed data
     * @param string function
     * @param mixed args
     * @return mixed
     */
    function call( $classId, $className, $constructorArgs, $data, $function, $args ) {

        $reflectionObj = new ReflectionClass( $className );
        $class = $reflectionObj->newInstanceArgs( $constructorArgs );
        if ( !empty( $data ) ) {
            foreach( $data as $k -> $d ) {
                $class->{$k} = $d;
            }
        }
        $ret = $this->callFunc( $class, $function, $args );
        $ret['remoteInSync'] = false;
        return $ret;
    }
    /**
     * Api privada y generica usada desde WSProxy.
     * ClassId es un uniqueId que permite identificar la clase para que
     * se puede mantener el estado del lado del server.
     * @param string classId
     * @param string function
     * @param mixed args
     * @return mixed
     */
    function callInSync( $classId, $function, $args ) {
        throw new Exception( 'must be implemented, see call->remoteInSync' );
        //Deserialize class.
        $class = null;
        $ret = $this->callFunc( $class, $function, $args );
        $ret['remoteInSync'] = false;
        return $ret;
    }

    private function callFunc( $class, $function, $arguments ) {
        $args = array();
        foreach( $arguments as $argument ) {
            $args[] = unserialize( base64_decode( $argument ) );
        }
        $funcRet = call_user_func_array( array( $class, $function ) , $args );

        // Serialize class to some cache based on classId then change remoteInSync to true
        $ret = array();
        $ret[ 'retval' ] = base64_encode( serialize( $funcRet ) );
        if ( is_object( $funcRet ) ) {
            $ret[ 'class' ] = get_class( $funcRet );
        } else {
            $ret[ 'type' ]  = gettype( $funcRet );
        }
        return $ret;
    }
    /**
     * Api privada y generica usada desde WSProxy.
     * @param string className
     * @param string function
     * @param mixed args
     * @return mixed
     */
    function callStatic( $className, $function, $args ) {
        return call_user_func_array( array( $className, $function ) , $args );
    }

}